import { LAYOUT, PageEnum } from '@/constants'
import { cloneDeep } from './lodash'
import { RouteMeta } from 'vue-router'

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
const LayoutMap = new Map<string, () => Promise<typeof import('*.vue')>>()

LayoutMap.set('LAYOUT', LAYOUT)
// LayoutMap.set('IFRAME', FrameBlank)

let dynamicViewsModules: Record<string, () => Promise<Recordable<any>>>
/**
 * @description: parent-layout
 */
export const getParentLayout = (_name?: string) => {
	return () =>
		new Promise((resolve) => {
			resolve({
				name: _name || 'ParentLayout'
			})
		})
}
// Dynamic introduction
function asyncImportRoute(routes: RouterType.RouteItem[] | undefined) {
	dynamicViewsModules =
		// eslint-disable-next-line @typescript-eslint/ban-ts-comment
		dynamicViewsModules || import.meta.glob('@/views/**/*.{vue,tsx}')

	if (!routes) return
	routes.forEach((item: any) => {
		if (!item.component && item.meta?.frameSrc) {
			item.component = 'IFRAME'
		}
		const { component, name } = item
		const { children } = item

		if (component) {
			const layoutFound = LayoutMap.get(component.toUpperCase())
			if (layoutFound) {
				item.component = layoutFound
			} else {
				item.component = dynamicImport(dynamicViewsModules, component as string)
			}
		} else if (name) {
			item.component = getParentLayout()
		}
		children && asyncImportRoute(children)
	})
}

function dynamicImport(dynamicViewsModules: Record<string, () => Promise<Recordable<any>>>, component: string) {
	const keys = Object.keys(dynamicViewsModules)
	const matchKeys = keys.filter((key) => {
		const k = key.replace('/src/views', '')
		const startFlag = component.startsWith('/')
		const endFlag = component.endsWith('.vue') || component.endsWith('.tsx')
		const startIndex = startFlag ? 0 : 1
		const lastIndex = endFlag ? k.length : k.lastIndexOf('.')
		return k.substring(startIndex, lastIndex) === component
	})
	if (matchKeys?.length === 1) {
		const matchKey = matchKeys[0]
		return dynamicViewsModules[matchKey]
	} else if (matchKeys?.length > 1) {
		console.warn(
			'Please do not create `.vue` and `.TSX` files with the same file name in the same hierarchical directory under the views folder. This will cause dynamic introduction failure'
		)
		return
	} else {
		console.warn('在/src下找不到`' + component + '.vue` 或 `' + component + '.tsx`, 请自行创建!')
		return PageEnum.ERROR_PAGE
	}
}

// Turn background objects into routing objects
export function transformObjToRoute(routeList: RouterType.RouteItem[]): RouterType.RouteItem[] {
	routeList.forEach((route) => {
		const _route: any = route
		const component = _route.component as string
		if (component) {
			if (component.toUpperCase() === 'LAYOUT') {
				route.component = LayoutMap.get(component.toUpperCase())
			} else {
				route.children = [cloneDeep(route)]
				route.component = LAYOUT
				route.name = `${_route.name}Parent`
				route.path = ''
				const meta = route.meta || ({} as RouteMeta)
				meta.single = true
				meta.affix = false
				route.meta = meta
			}
		} else {
			console.warn('请正确配置路由：' + _route?.name + '的component属性')
		}
		route.children && asyncImportRoute(route.children)
	})
	return routeList as unknown as RouterType.RouteItem[]
}
